// BSLLS-off

// Этот плагин выполняет переименование переменных если это возможно.
// При возникновении конфликтов регистрирует ошибку, которая указывает на конфликтную переменную.

// Пример ожидаемой структуры параметров (json):
// {"СтароеИмя1": "НовоеИмя1", "СтароеИмя2": "НовоеИмя2"}

Перем Токены;
Перем Типы;
Перем ТаблицаОшибок;
Перем ТаблицаЗамен;
Перем Директивы;

Перем Результат;

Перем МассивМетодов;
Перем ПрефиксПеременныхИПроцедур;

Процедура Открыть(Парсер, Параметры) Экспорт
	Типы = Парсер.Типы();
	ТаблицаОшибок = Парсер.ТаблицаОшибок();
	ТаблицаЗамен = Парсер.ТаблицаЗамен();
	Директивы = Парсер.Директивы();
	Токены = Парсер.Токены();
	
	Результат = Новый Массив;

	ПрефиксПеременныхИПроцедур=Параметры.ПрефиксПеременныхИПроцедур;
	МассивМетодов=Новый Массив;
КонецПроцедуры // Открыть()

Функция Закрыть() Экспорт
	Возврат СтрСоединить(Результат);
КонецФункции // Закрыть()

Функция Подписки() Экспорт
	Перем Подписки;
	Подписки = Новый Массив;
	Подписки.Добавить("ПосетитьОбъявлениеМетода");
	Подписки.Добавить("ПокинутьМодуль");
	Возврат Подписки;
КонецФункции // Подписки()

#Область РеализацияПодписок

Процедура ПосетитьОбъявлениеМетода(Описание) Экспорт
	Метод=Новый Структура;
	Метод.Вставить("Имя", Описание.Сигнатура.Имя);
	Метод.Вставить("Тип", Описание.Сигнатура.Тип);
	Метод.Вставить("Параметры", Описание.Сигнатура.Параметры);
	МассивМетодов.Добавить(Метод);

	Если Описание.Операторы.Количество()>0 Тогда
		ТекстПроцедуры=ПрефиксПеременныхИПроцедур+Описание.Сигнатура.Имя+"(";

		Первый=Истина;
		Для Каждого ПараметрМетода ИЗ Описание.Сигнатура.Параметры Цикл
			ТекстПроцедуры=ТекстПроцедуры+?(Не Первый,",","")+ПараметрМетода.Имя;

			Первый=Ложь;
		КонецЦикла;
		ТекстПроцедуры=ТекстПроцедуры+")";

		Если Описание.Сигнатура.Тип=Типы.ОбъявлениеСигнатурыФункции Тогда
			ТекстПроцедуры="Возврат "+ТекстПроцедуры;
		КонецЕсли;
		Замена(ТекстПроцедуры, Описание.Операторы[0].Начало,Описание.Операторы[Описание.Операторы.Количество()-1].Конец);

	КонецЕсли;
КонецПроцедуры

Процедура ПокинутьМодуль(Описание) Экспорт
	Если МассивМетодов.Количество()=0 Тогда
		Возврат;
	КонецЕсли;

	ТекстСерверныхВызовов="
	|&НаСервере
	|Функция "+ПрефиксПеременныхИПроцедур+"ОбъектМодуля()
	|	Возврат РеквизитФормыВЗначение(""Объект"");
	|КонецФункции
	|
	|";
	Для Каждого Метод Из МассивМетодов Цикл
		ТекстСерверныхВызовов=ТекстСерверныхВызовов+"
		|&НаСервере";
		Если Метод.Тип=Типы.ОбъявлениеСигнатурыФункции Тогда
			ТекстСерверныхВызовов=ТекстСерверныхВызовов+"
			|Функция ";
		Иначе
			ТекстСерверныхВызовов=ТекстСерверныхВызовов+"
			|Процедура ";
		КонецЕсли;
		
		ТекстСерверныхВызовов=ТекстСерверныхВызовов+ПрефиксПеременныхИПроцедур+Метод.Имя+"(";

		ТекстПараметров="";
		Первый=Истина;
		Для Каждого ПараметрМетода ИЗ Метод.Параметры Цикл
			ТекстПараметров=ТекстПараметров+?(Не Первый,",","")+ПараметрМетода.Имя;

			Первый=Ложь;
		КонецЦикла;
		ТекстСерверныхВызовов=ТекстСерверныхВызовов+ТекстПараметров+")
		|	";

		Если Метод.Тип=Типы.ОбъявлениеСигнатурыФункции Тогда
			ТекстСерверныхВызовов=ТекстСерверныхВызовов+"Возврат ";
		КонецЕсли;

		ТекстСерверныхВызовов=ТекстСерверныхВызовов+ПрефиксПеременныхИПроцедур+"ОбъектМодуля()."+Метод.Имя+"("+ТекстПараметров+");";

		Если Метод.Тип=Типы.ОбъявлениеСигнатурыФункции Тогда
			ТекстСерверныхВызовов=ТекстСерверныхВызовов+"
			|КонецФункции";
		Иначе
			ТекстСерверныхВызовов=ТекстСерверныхВызовов+"
			|КонецПроцедуры";
		КонецЕсли;

	КонецЦикла;

	Конец=Описание.Объявления[Описание.Объявления.Количество()-1].Конец;
	Вставка(ТекстСерверныхВызовов,Конец.Позиция+Конец.Длина);
КонецПроцедуры

#КонецОбласти // РеализацияПодписок

Процедура Ошибка(Текст, Начало, Конец = Неопределено, ЕстьЗамена = Ложь)
	Ошибка = ТаблицаОшибок.Добавить();
	Ошибка.Источник = "ЗаменаВызоваПроцедурВызовСервера";
	Ошибка.Текст = Текст;
	Ошибка.ПозицияНачала = Начало.Позиция;
	Ошибка.НомерСтрокиНачала = Начало.НомерСтроки;
	Ошибка.НомерКолонкиНачала = Начало.НомерКолонки;
	Если Конец = Неопределено Или Конец = Начало Тогда
		Ошибка.ПозицияКонца = Начало.Позиция + Начало.Длина;
		Ошибка.НомерСтрокиКонца = Начало.НомерСтроки;
		Ошибка.НомерКолонкиКонца = Начало.НомерКолонки + Начало.Длина;
	Иначе
		Ошибка.ПозицияКонца = Конец.Позиция + Конец.Длина;
		Ошибка.НомерСтрокиКонца = Конец.НомерСтроки;
		Ошибка.НомерКолонкиКонца = Конец.НомерКолонки + Конец.Длина;
	КонецЕсли;
	Ошибка.ЕстьЗамена = ЕстьЗамена;
КонецПроцедуры

Процедура Замена(Текст, Начало, Конец = Неопределено)
	НоваяЗамена = ТаблицаЗамен.Добавить();
	НоваяЗамена.Источник = "ЗаменаВызоваПроцедурВызовСервера";
	НоваяЗамена.Текст = Текст;
	НоваяЗамена.Позиция = Начало.Позиция;
	Если Конец = Неопределено Тогда
		НоваяЗамена.Длина = Начало.Длина;
	Иначе
		НоваяЗамена.Длина = Конец.Позиция + Конец.Длина - Начало.Позиция;
	КонецЕсли;
КонецПроцедуры

Процедура Вставка(Текст, Позиция)
	НоваяЗамена = ТаблицаЗамен.Добавить();
	НоваяЗамена.Источник = "ЗаменаВызоваПроцедурВызовСервера";
	НоваяЗамена.Текст = Текст;
	НоваяЗамена.Позиция = Позиция;
	НоваяЗамена.Длина = 0;
КонецПроцедуры